﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml;

using FRL.DebtChased.Extensions;
using FRL.DebtChased.Repository;
using FRL.DebtChased.Silverlight.Library;
using FRL.DebtChased.Silverlight.Library.RichContentService;
using FRL.DebtChased.WorkflowObjects;

namespace FRL.DebtChased.WorkflowEditor
{

	/// <summary>
	/// Declaration of MainPage class
	/// </summary>
	public partial class MainPage : UserControl, IDebtChasedMainPlugInWindow
	{

		/////////////////////////////////////////////////////////////
		// Constants

		private const string Action_PickAction = "[Pick Action]";

		private const string Action_Edit = "Edit";

		private const string Action_Clone = "Clone";

		private const string Action_Superceed = "Superceed";

		private const string Action_Retire = "Retire";

		private const string Action_Delete = "Delete";

		/////////////////////////////////////////////////////////////
		// Attributes

		private static MainPage m_singleton = null;
		public static MainPage Singleton
		{
			get { return m_singleton; }
		}

		private int m_iClientId = 0;

		/////////////////////////////////////////////////////////////
		// Construction

		public MainPage()
		{

			// Initialize member variables
			m_singleton = this;

			// Initialize components
			InitializeComponent();

			// Setup library
			new LibrarySession(this);

			// Set controls
			tbClientName.Text = "";

			// Setup animations
			fadeInWorkflowEditor.Completed += new EventHandler(fadeInWorkflowEditor_Completed);
			fadeOutWorkflowEditor.Completed += new EventHandler(fadeOutWorkflowEditor_Completed);

			// Do the initial load of data
			_loadSupportData();

			// Setup controls
			_setupControls();

		}

		/////////////////////////////////////////////////////////////
		// Implementation of IDebtChasedMainPlugInWindow

		public void ShowHourglass(bool bTrue)
		{

			// Show/hide hourglass
			hourglassCtrl.IncShowCount(bTrue);

		}

		public void WebsiteMenuClicked(DebtChasedWebsiteMenuCtrl.eMenuItem menuItemId)
		{
			throw new NotImplementedException();
		}

		public void ContactPointButtonClick(PointActiveButton button, int iContactId, Guid contactPointId)
		{
			throw new NotImplementedException();
		}

		/////////////////////////////////////////////////////////////
		// Event Handlers

		private void butSearch_Click(object sender, RoutedEventArgs e)
		{

			// Search for clients

			// if this is a default load...
			if (chkDefaultClient.IsChecked ?? false)
			{

				// Load the client
				_refreshWorkflowList(0);

			}
			else
			{

				// Check search text
				if (txtSearch.Text.Length < 3)
					MessageBoxes.PopupMessage("Search text must be 3 or more characters.");
				else
					_clientSearch(txtSearch.Text);

			}

		}

		private void chkDefaultClient_Click(object sender, RoutedEventArgs e)
		{

			// Setup controls
			_setupControls();

		}

		void cboActions_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{

			// Get the action
			ComboBox cboAction = sender as ComboBox;
			string strAction = cboAction.SelectedValue.ToString();
			if (strAction == Action_PickAction)
				return;

			// Get the source row
			int iRowIndex = Grid.GetRow(cboAction);

			// Get workflow id
			int iWorkflowId = _getWorkflowIdAtRowIndex(iRowIndex);

			// Compare actions
			if (strAction == Action_Edit)
			{

				// Load the workflow and edit
				_loadWorkflowAndEdit(iWorkflowId);

			}
			else
				MessageBoxes.PopupDevMessage();

			// Reset action
			cboAction.SelectedIndex = 0;
			
		}

		void EditInvoiceStatusButton_Click(object sender, EventArgs e)
		{

			// Get the source row
			int iRowIndex = Grid.GetRow(sender as PathButton);

			// Get invoice-status id
			int iInvoiceStatusId = _getInvoiceStatusIdAtRowIndex(iRowIndex);

			// Load status for editing
			_loadInvoiceStatusForEditing(iInvoiceStatusId);

		}

		/////////////////////////////////////////////////////////////
		// Operations

		private void _setupControls()
		{

			// Enable/disable controls
			txtSearch.IsEnabled = (!(chkDefaultClient.IsChecked ?? false));

		}

		private int _getWorkflowIdAtRowIndex(int iRowIndex)
		{

			// Declare return variable
			int iFtmp = 0;

			// Get the status textbox
			ComboBox cboWorkflow = gridWorkflow.FindCellContent(2, iRowIndex, typeof(ComboBox)) as ComboBox;
#if DEBUG
			Debug.Assert(cboWorkflow != null);
#endif // #if DEBUG
			iFtmp = (cboWorkflow.SelectedValue as ComboBoxObject).ItemData;

			// Return variable
			return iFtmp;

		}

		private int _getInvoiceStatusIdAtRowIndex(int iRowIndex)
		{

			// Declare return variable
			int iFtmp = 0;

			// Get the status textbox
			TextRectangleCtrl tr = gridWorkflow.FindCellContent(1, iRowIndex, typeof(TextRectangleCtrl)) as TextRectangleCtrl;
#if DEBUG
			Debug.Assert(tr != null);
#endif // #if DEBUG
			iFtmp = (int)tr.Tag;

			// Return variable
			return iFtmp;

		}

		private void _addRow( ObservableCollection<WorkflowSummaryTransport> workflowList )
		{

			// Add a new row
			RowDefinition newRow = new RowDefinition();
			newRow.Height = new GridLength(0, GridUnitType.Auto);
			gridWorkflow.RowDefinitions.Add(newRow);
			int iRowIndex = gridWorkflow.RowDefinitions.Count - 1;

			// Add controls
			PathButton editButton = new PathButton();
			editButton.Image = PathButton.eImage.Browse;
			editButton.Width = 22;
			editButton.Height = 22;
			editButton.Click += new EventHandler(EditInvoiceStatusButton_Click);
			gridWorkflow.Children.Add(editButton);
			Grid.SetColumn(editButton, 0);
			Grid.SetRow(editButton, iRowIndex);

			TextRectangleCtrl trStatusName = new TextRectangleCtrl();
			trStatusName.Style = this.Resources["TextRectangleStyle"] as Style;
			trStatusName.InnerMargin = new Thickness(10,0,0,0);
			gridWorkflow.Children.Add(trStatusName);
			Grid.SetColumn(trStatusName, 1);
			Grid.SetRow(trStatusName, iRowIndex);

			ComboBox cboWorkflow = new ComboBox();
			//cboWorkflow.Style = this.Resources["FatBlueComboBoxStyle"] as Style;
			gridWorkflow.Children.Add(cboWorkflow);
			Grid.SetColumn(cboWorkflow, 2);
			Grid.SetRow(cboWorkflow, iRowIndex);

			TextBlock lbSummary = new TextBlock();
			lbSummary.Style = this.Resources["FatBlueTextBlockStyle"] as Style;
			gridWorkflow.Children.Add(lbSummary);
			Grid.SetColumn(lbSummary, 3);
			Grid.SetRow(lbSummary, iRowIndex);

			ComboBox cboActions = new ComboBox();
			cboActions.SelectionChanged += new SelectionChangedEventHandler(cboActions_SelectionChanged);
			//cboActions.Style = this.Resources["FatBlueComboBoxStyle"] as Style;
			gridWorkflow.Children.Add(cboActions);
			Grid.SetColumn(cboActions, 4);
			Grid.SetRow(cboActions, iRowIndex);

			Button butHistory = new Button();
			butHistory.Style = this.Resources["HistoryButtonStyle"] as Style;
			butHistory.Click += new RoutedEventHandler(butHistory_Click);
			gridWorkflow.Children.Add(butHistory);
			Grid.SetColumn(butHistory, 5);
			Grid.SetRow(butHistory, iRowIndex);

			// Load actions
			cboActions.Items.Add(Action_PickAction);
			cboActions.Items.Add(Action_Edit);
			cboActions.Items.Add(Action_Clone);
			cboActions.Items.Add(Action_Superceed);
			cboActions.Items.Add(Action_Retire);
			cboActions.Items.Add(Action_Delete);

		}

		private void _removeRow()
		{

			// Delete the bottom row
			int iRowIndex = gridWorkflow.RowDefinitions.Count - 1;
			gridWorkflow.DeleteRows(iRowIndex, 1);

		}

		private void _getControls( int iRowIndex, ref TextRectangleCtrl trStatusName, ref ComboBox cboWorkflow, ref TextBlock lbSummary, ref ComboBox cboActions, ref Button butHistory )
		{

			// Reset function parameters
			trStatusName = null;
			lbSummary = null;
			cboWorkflow = null;
			cboWorkflow = null;
			butHistory = null;

			// Loop through controls
			foreach (UIElement uiElement in gridWorkflow.Children)
			{

				// Ignore any non-framework...
				FrameworkElement el = uiElement as FrameworkElement;
				if (el == null)
					continue;

				// Compare rows				
				if (Grid.GetRow(el) == iRowIndex)
				{

					// Compare columns
					int iColumn = Grid.GetColumn(el);
					if (iColumn == 0)
					{

						// Ignore button

					}
					else if (iColumn == 1)
					{
#if DEBUG
						Debug.Assert(trStatusName == null);
#endif // #if DEBUG
						trStatusName = el as TextRectangleCtrl;
					}
					else if (iColumn == 2)
					{
#if DEBUG
						Debug.Assert(cboWorkflow == null);
#endif // #if DEBUG
						cboWorkflow = el as ComboBox;
					}
					else if (iColumn == 3)
					{
#if DEBUG
						Debug.Assert(lbSummary == null);
#endif // #if DEBUG
						lbSummary = el as TextBlock;
					}
					else if (iColumn == 4)
					{
#if DEBUG
						Debug.Assert(cboActions == null);
#endif // #if DEBUG
						cboActions = el as ComboBox;
					}
					else if (iColumn == 5)
					{
#if DEBUG
						Debug.Assert(butHistory == null);
#endif // #if DEBUG
						butHistory = el as Button;
					}
#if DEBUG
					else
						Debug.Assert(false);
#endif // #if DEBUG

				}

			}

			// Check function parameters
#if DEBUG
			Debug.Assert(trStatusName != null);
			Debug.Assert(lbSummary != null);
			Debug.Assert(cboWorkflow != null);
			Debug.Assert(cboWorkflow != null);
			Debug.Assert(butHistory != null);
#endif // #if DEBUG

		}

		private void _setRow( int iRowIndex, AccountInvoiceStatusTransport status, ObservableCollection<WorkflowSummaryTransport> workflowList )
		{

			// Get controls
			TextRectangleCtrl trStatusName = null;
			ComboBox cboWorkflow = null;
			TextBlock lbSummary = null;
			ComboBox cboActions = null;
			Button butHistory = null;
			_getControls(iRowIndex, ref trStatusName, ref cboWorkflow, ref lbSummary, ref cboActions, ref butHistory);

			// Set controls
			trStatusName.Text = status.InvoiceStatusName;
			trStatusName.Tag = status.AccountInvoiceStatusId;

			// Clear the workflows
			cboWorkflow.Items.Clear();

			// If this is the default set...
			if (m_iClientId == 0)
			{
#if DEBUG
				Debug.Assert(status.DefaultWorkflowId == status.ClientWorkflowId);
#endif // #if DEBUG

				// Load workflows
				foreach (WorkflowSummaryTransport wst in workflowList)
				{
					if (wst.InvoiceStatusId == status.AccountInvoiceStatusId)
						cboWorkflow.Items.Add(new ComboBoxObject(wst.WorkflowName, wst.WorkflowId, wst.Summary));
				}
#if DEBUG
				Debug.Assert(cboWorkflow.Items.Count > 0);
#endif // #if DEBUG
				ComboBoxObject.SelectByItemData(cboWorkflow, status.DefaultWorkflowId);

			}
			else
			{

				// Load workflows
				foreach (WorkflowSummaryTransport wst in workflowList)
				{

					// Ignore workflows not in this status
					if (wst.InvoiceStatusId != status.AccountInvoiceStatusId)
						continue;

					// Get name of workflow
					string strName;
					if (wst.WorkflowId == status.DefaultWorkflowId)
						strName = string.Format("{0} - {1}", Definitions.Default, wst.WorkflowName);
					else
						strName = wst.WorkflowName;

					// Add item to combo
					cboWorkflow.Items.Add(new ComboBoxObject(strName, wst.WorkflowId, wst.Summary));

				}
				if(status.ClientWorkflowId != 0)
					ComboBoxObject.SelectByItemData(cboWorkflow, status.ClientWorkflowId);
				else
					ComboBoxObject.SelectByItemData(cboWorkflow, status.DefaultWorkflowId);

			}

			// Set action
			cboActions.SelectedIndex = 0;

		}

		private void _showWorkflowEditingCtrl(int iWorkflowId, int iAccountInvoiceStatusId, bool bIsInstalmentPlanStatus, FRL.DebtChased.WorkflowObjects.Workflow wf)
		{

			// Set workflow data
			workflowEditingCtrl.SetWorkflow(iWorkflowId, iAccountInvoiceStatusId, bIsInstalmentPlanStatus, wf);

			// Show the workflow editing control
			canvasBacking.Opacity = 0.0;
			canvasBacking.Visibility = System.Windows.Visibility.Visible;
			fadeInWorkflowEditor.Begin();

		}

		public void CloseWorkflowEditingCtrl()
		{

			// Hide the editor control
			workflowEditingCtrl.Visibility = System.Windows.Visibility.Collapsed;

			// Hide the workflow editing control
			fadeOutWorkflowEditor.Begin();

		}

		void fadeInWorkflowEditor_Completed(object sender, EventArgs e)
		{

			// Show the editor control
			workflowEditingCtrl.Visibility = System.Windows.Visibility.Visible;

		}

		void fadeOutWorkflowEditor_Completed(object sender, EventArgs e)
		{

			// Hide the canvas
			canvasBacking.Visibility = System.Windows.Visibility.Collapsed;
			
		}

		void butHistory_Click(object sender, RoutedEventArgs e)
		{
			MessageBoxes.PopupDevMessage();
		}

		private void butNewInvoiceStatus_Click(object sender, RoutedEventArgs e)
		{

			// Show new-status window
			NewInvoiceStatusWnd wnd = new NewInvoiceStatusWnd();
			wnd.Closed += new EventHandler(NewInvoiceStatusWnd_Closed);
			wnd.Show();

		}

		void NewInvoiceStatusWnd_Closed(object sender, EventArgs e)
		{

			// If there is a new invoice-status...
			NewInvoiceStatusWnd wnd = sender as NewInvoiceStatusWnd;
			if (wnd.DialogResult ?? false)
			{

				// Reload the list
				_refreshWorkflowList(m_iClientId);

			}
			
		}

		/////////////////////////////////////////////////////////////
		#region Operations loading and saving data

		private void _loadSupportData()
		{
#if DEBUG
			Debug.Assert(CachedData.Singleton.CommBodies == null);
#endif // #if DEBUG

			// Show hourglass
			hourglassCtrl.IncShowCount(true);

			// Load real or fake supporting data
#if USEFAKEDATA

			// Create event
			object[] results = new object[1];
			results[0] = CachedData.GetDummySupportingData();
			GetWorkflowSupportDataCompletedEventArgs e = new GetWorkflowSupportDataCompletedEventArgs(
				results,
				null,
				false,
				null
			);

			// Call completed event
			proxy_GetWorkflowSupportDataCompleted(null, e);

#else

			// Start by downloading the supporting data
			RichContentServiceClient proxy = new RichContentServiceClient();
			proxy.GetWorkflowSupportDataCompleted += new EventHandler<GetWorkflowSupportDataCompletedEventArgs>(proxy_GetWorkflowSupportDataCompleted);
			proxy.Endpoint.Address = ExtensionsForSilverlight.CreateDebtChasedEndpoint();
			proxy.GetWorkflowSupportDataAsync();

#endif // #if USEFAKEDATA

		}

		void proxy_GetWorkflowSupportDataCompleted(object sender, GetWorkflowSupportDataCompletedEventArgs e)
		{

			// Hide hourglass
			hourglassCtrl.IncShowCount(false);

			// Get the result
			if (e.Error != null)
				MessageBoxes.PopupMessage(e.Error.Message);
			else if (e.Result == null)
				MessageBoxes.PopupMessage_InternalError("Failed to load supporting data from server.");
			else
			{

				// Update the cached data
				CachedData.Singleton.AddIncoming(e.Result);

				// Setup the tabs
				workflowEditingCtrl.SupportDataLoaded();

				// Load the list of workflows
				_refreshWorkflowList(0);

			}

			// Setup controls
			_setupControls();

		}

		private void _refreshWorkflowList(int iClientId)
		{

			// Show hourglass
			hourglassCtrl.IncShowCount(true);

			// Load real or fake workflows
#if USEFAKEDATA

			// Create event
			object[] results = new object[1];
			results[0] = CachedData.GetDummyWorkflowList(iClientId);
			GetWorkflowsTransportWrapperCompletedEventArgs e = new GetWorkflowsTransportWrapperCompletedEventArgs(
				results,
				null,
				false,
				null
			);

			// Call completed event
			proxy_GetWorkflowsTransportWrapperCompleted(null, e);

#else

			// Start by downloading the supporting data
			RichContentServiceClient proxy = new RichContentServiceClient();
			proxy.GetWorkflowsTransportWrapperCompleted += new EventHandler<GetWorkflowsTransportWrapperCompletedEventArgs>(proxy_GetWorkflowsTransportWrapperCompleted);
			proxy.Endpoint.Address = ExtensionsForSilverlight.CreateDebtChasedEndpoint();
			proxy.GetWorkflowsTransportWrapperAsync(iClientId);

#endif // #if USEFAKEDATA

		}

		private void _loadWorkflowAndEdit( int iWorkflowId )
		{

			// Show hourglass
			hourglassCtrl.IncShowCount(true);

			// Load real or fake workflow
#if USEFAKEDATA

			// Make buffer
			WorkflowTransportWrapper wrapper = new WorkflowTransportWrapper();
			wrapper.Buffer = (new Workflow()).ToXmlBuffer();
			wrapper.WorkflowId = iWorkflowId;
			wrapper.IsInstalmentPlanStatus = (iWorkflowId==101);
			wrapper.AccountInvoiceStatusId = 1;

			// Create event
			object[] results = new object[2];
			results[0] = iWorkflowId;
			results[1] = wrapper;
			GetWorkflowXmlCompletedEventArgs e = new GetWorkflowXmlCompletedEventArgs(
				results,
				null,
				false,
				null
			);

			// Call completed event
			proxy_GetWorkflowXmlCompleted(null, e);

#else

			// Start by downloading the supporting data
			RichContentServiceClient proxy = new RichContentServiceClient();
			proxy.GetWorkflowXmlCompleted += new EventHandler<GetWorkflowXmlCompletedEventArgs>(proxy_GetWorkflowXmlCompleted);
			proxy.Endpoint.Address = ExtensionsForSilverlight.CreateDebtChasedEndpoint();
			proxy.GetWorkflowXmlAsync(iWorkflowId);

#endif // #if USEFAKEDATA

		}

		void proxy_GetWorkflowXmlCompleted(object sender, GetWorkflowXmlCompletedEventArgs e)
		{

			// Hide hourglass
			hourglassCtrl.IncShowCount(false);

			// If the call failed...
			if(e.Error != null)
			{
				MessageBoxes.PopupMessage_InternalError(e.Error.Message);
			}
			else if (e.Result == null)
			{
#if DEBUG
				Debug.Assert(false);
#endif // #if DEBUG
			}
			else
			{

				// Unwrap the workflow
				FRL.DebtChased.WorkflowObjects.Workflow wf = FRL.DebtChased.WorkflowObjects.Workflow.XmlFactory(e.Result.Buffer);
				if (wf != null)
				{

					// Show the workflow ctrl
					_showWorkflowEditingCtrl(
						e.Result.WorkflowId, 
						e.Result.AccountInvoiceStatusId,
						e.Result.IsInstalmentPlanStatus,
						wf 
					);

				}
				else
					MessageBoxes.PopupMessage_InternalError("Cannot load workflow.  Failed to unwrap xml data.");

			}

			// Setup controls
			_setupControls();

		}

		void proxy_GetWorkflowsTransportWrapperCompleted(object sender, GetWorkflowsTransportWrapperCompletedEventArgs e)
		{

			// Hide hourglass
			hourglassCtrl.IncShowCount(false);

			// Get the result
			if (e.Error != null)
				MessageBoxes.PopupMessage(e.Error.Message);
			else if (e.Result == null)
				MessageBoxes.PopupMessage_InternalError("Failed to load workflows from server.");
			else
			{

				// Retain the client details
				m_iClientId = e.Result.ClientId;
				if(m_iClientId == 0)
					tbClientName.Text = Definitions.Default;
				else
					tbClientName.Text = e.Result.ClientName;

				// Reload the grid
				int iRowsRequired = e.Result.AccountInvoiceStatusList.Count + 1;
				while (iRowsRequired > gridWorkflow.RowDefinitions.Count)
					_addRow(e.Result.WorkflowList);
				while (iRowsRequired < gridWorkflow.RowDefinitions.Count)
					_removeRow();

				// Set the rows
				for (int i1 = 0; i1 < e.Result.AccountInvoiceStatusList.Count; i1++)
					_setRow( 1 + i1, e.Result.AccountInvoiceStatusList[i1], e.Result.WorkflowList );

			}

			// Setup controls
			_setupControls();

		}

		private void _clientSearch(string strSearch)
		{

			// Show hourglass
			hourglassCtrl.IncShowCount(true);

			try
			{

				// Initialize a save function
				RichContentServiceClient proxy = new RichContentServiceClient();
				proxy.SearchClientsCompleted += new EventHandler<SearchClientsCompletedEventArgs>(proxy_SearchClientsCompleted);
				proxy.Endpoint.Address = ExtensionsForSilverlight.CreateDebtChasedEndpoint();
				proxy.SearchClientsAsync(strSearch);

			}
			catch (Exception x)
			{

				// Message for user
				MessageBoxes.PopupMessage_InternalError(string.Format("Failed to search clients.\n\n{0}", x.ToDetailsString()));

			}

		}

		void proxy_SearchClientsCompleted(object sender, SearchClientsCompletedEventArgs e)
		{

			// Hide hourglass
			hourglassCtrl.IncShowCount(false);

			// Get the result
			if (e.Error != null)
				MessageBoxes.PopupMessage(e.Error.Message);
			else if (e.Result == null)
				MessageBoxes.PopupMessage(Definitions.InternalError);
			else
			{

				// If there are some results
				if (e.Result.Count > 0)
				{
					ClientSearchResultsWnd wndResults = new ClientSearchResultsWnd(e.Result.ToList());
					wndResults.Closed += new EventHandler(wndResults_Closed);
					wndResults.Show();
				}
				else
					MessageBoxes.PopupMessage("Search returned no results.");

			}

			// Setup controls
			_setupControls();

		}

		void wndResults_Closed(object sender, EventArgs e)
		{

			// Get the selected id
			ClientSearchResultsWnd wnd = sender as ClientSearchResultsWnd;
			if (wnd.DialogResult == true)
				_refreshWorkflowList(wnd.SelectedClientId);

		}

		private void _loadInvoiceStatusForEditing(int iInvoiceStatusId)
		{
#if DEBUG
			Debug.Assert(iInvoiceStatusId != 0);
#endif // #if DEBUG

			// Show hourglass
			hourglassCtrl.IncShowCount(true);

			// Start by downloading the supporting data
			RichContentServiceClient proxy = new RichContentServiceClient();
			proxy.Endpoint.Address = ExtensionsForSilverlight.CreateDebtChasedEndpoint();
			proxy.GetInvoiceStatusCompleted += new EventHandler<GetInvoiceStatusCompletedEventArgs>(proxy_GetInvoiceStatusCompleted);
			proxy.GetInvoiceStatusAsync(iInvoiceStatusId);

		}

		void proxy_GetInvoiceStatusCompleted(object sender, GetInvoiceStatusCompletedEventArgs e)
		{

			// Hide hourglass
			hourglassCtrl.IncShowCount(false);

			// Get the result
			if (e.Error != null)
				MessageBoxes.PopupMessage(e.Error.Message);
			else if (e.Result == null)
				MessageBoxes.PopupMessage(Definitions.InternalError);
			else
			{

				// Edit the invoice status
				EditInvoiceStatusWnd wnd = new EditInvoiceStatusWnd(e.Result);
				wnd.Closed += new EventHandler(EditInvoiceStatusWnd_Closed);
				wnd.Show();

			}

			// Setup controls
			_setupControls();

		}

		void EditInvoiceStatusWnd_Closed(object sender, EventArgs e)
		{

			// If invoice-status has been edited...
			EditInvoiceStatusWnd wnd = sender as EditInvoiceStatusWnd;
			if (wnd.DialogResult ?? false)
			{

				// Reload the list
				_refreshWorkflowList(m_iClientId);

			}

		}

		#endregion Operations loading and saving data

	}

}
